const Buffer = require('buffer').Buffer
const net = require('net')
const logger = require('./console-logger')


// 帧头(2)+帧版本（1）+帧总数（1）+帧序号（1）+帧长度(2)+备用（1）+设备ID（1）+命令码(2)+内容(N)+校验码(1)
// 1.0 帧头：0xF7,0x7F。
// 1.1 帧版本号：（1字节Hex码）
// 1.2 帧总数：（1字节Hex码）本次数据传输要传的总帧数。
// 1.3 帧序号：（1字节Hex码）当前传输帧的序号。
// 1.4 帧长度：（2字节Hex码）高字节在靠近帧头。包括“帧头”到“校验码”的所有字节数。
// 1.5 设备硬件状态码：（1字节Hex码）默认为0（备注：各硬件状态值详见硬件状态码表）
// 1.6 设备ID：（1字节Hex码）（备注：取值范围为1到255，0为内部测试使用，默认为1）
// 1.7 命令码（2字节Hex码）：命令代码。下详。
// 1.8 内容（N字节Hex码）：内容定义详见对应命令。
// 1.9 校验和（1字节Hex码）：仅计算从帧头到内容的校验和，计算方式为：以字节为单位进行加计算，计算出总和后再加1，取低8位。

const buf0 = [0xf7, 0x7f]
const buf1 = [0x01]
const buf2 = [0x01]
const buf3 = [0x01]
const buf4 = [0x00, 0x0c] // 帧长度,需计算
const buf5 = [0x00]
const buf6 = [0x01]
const buf7 = [0x00, 0x00] // 命令码,根据指令设置
const buf8 = [0x01] // 内容,根据指令设置
const buf9 = [0x00] // 校验帧,需要计算

const baseBuf = [0xF7, 0x7F, 0x01, 0x01, 0x01, 0x00, 0x0C, 0x00, 0x01]

// 计算帧长度、校验帧
function finalBuf(action, content) {
    const buf = Buffer.concat([Buffer.from(baseBuf), action, content, Buffer.from([0x00])])
    // 1.
    const length = buf.length
    const lenHigh = (length & 0xff00) >> 8
    const lenLow = (length & 0xff)
    buf[5] = lenHigh
    buf[6] = lenLow
    // 2.
    buf[length - 1] = calCrc(buf)

    return buf
}

function calCrc(buf) {
    let sum = 0
    for (const b of buf.values()) {
        sum += b 
    }
    return (sum + 1 & 0xff)
}

class Device {
    constructor(ip, port, ssid) {
        this.ip = ip
        this.port = port
        this.ssid = ssid
    }

    init() {
        this.client = net.Socket();

        // 连接 tcp server
        this.client.connect({
            host : '192.168.4.1',  
            port : 8888
        }, function(){
            console.log('connected to Server');
        })

        // 接收数据
        this.client.on('data',function(data){
            console.log('received data: %s from server', data.toString());
        })

        this.client.on('end',function(){
            console.log('data end!');
        })

        this.client.on('error', function (error) {
            console.log('tcp_client error!', error);
        })
    }

    close() {
        this.client.destroy()
    }

    sendAction(action, content) {
        if (!this.client) {
            logger.error('ERROR: Please device.init() first!')
            return
        } 
        const sendBuf = finalBuf(action, content)
        logger.debug('sendBuf:', sendBuf)
        
        this.client.write(sendBuf, (data) => {
            console.log('sended, got:', data);
        });
    }
    
    // 握手指令
    shakeHand() {
        const action = Buffer.from([0x00, 0x01])
        const content = Buffer.concat([Buffer.from([0xaa]), Buffer.from(this.ssid)])  // 固定值0xAA+12位SSID
        this.sendAction(action, content)
    }

    // 设置连接WIFI
    setWifi() {
        const action = Buffer.from([0x00, 0x02])
        const content = Buffer.concat([Buffer.from([0xaa]), Buffer.from(this.ssid)])  // 固定值0xAA+12位SSID
        this.sendAction(action, content)
    }
}

const device = new Device('192.168.4.1', 8888, 'IYK_RQS568BN')
device.init()
device.shakeHand()

setTimeout(()=> {
    device.close()
}, 3000)
